

#include <jni.h>
#include <vector.h>
#include "net_matvec_Vector.h"


void _make_vect(double *vect_data, vm_vector *result){

  result->x = vect_data[0];
  result->y = vect_data[1];
  result->z = vect_data[2];
  result->w = vect_data[3];

}

void Java_net_matvec_Vector_vm_1add(JNIEnv *env, 
	  jobject obj, jdoubleArray v1, jdoubleArray v2, jdoubleArray res){

  vm_vector *vect1 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v1, NULL);
  vm_vector *vect2 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v2, NULL);
  vm_vector *result = (vm_vector *)(*env)->
    GetDoubleArrayElements(env, res, NULL);

  vm_add(*vect1, *vect2, result);

  (*env)->ReleaseDoubleArrayElements(env, v1, (jdouble *)vect1, 0);
  (*env)->ReleaseDoubleArrayElements(env, v2, (jdouble *)vect2, 0);
  (*env)->ReleaseDoubleArrayElements(env, res, (jdouble *)result, 0);

}

void Java_net_matvec_Vector_vm_1sub(JNIEnv * env, 
          jobject obj, jdoubleArray v1, jdoubleArray v2, jdoubleArray res){

  vm_vector *vect1 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v1, NULL);
  vm_vector *vect2 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v2, NULL);
  vm_vector *result = (vm_vector *)(*env)->
    GetDoubleArrayElements(env, res, NULL);

  vm_sub(*vect1, *vect2, result);

  (*env)->ReleaseDoubleArrayElements(env, v1, (jdouble *)vect1, 0);
  (*env)->ReleaseDoubleArrayElements(env, v2, (jdouble *)vect2, 0);
  (*env)->ReleaseDoubleArrayElements(env, res, (jdouble *)result, 0);

}

void Java_net_matvec_Vector_vm_1scale(JNIEnv *env, 
          jobject obj, jdoubleArray v, jdouble d, jdoubleArray res){

  vm_vector *vect = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v, NULL);
  vm_vector *result = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, res, NULL);

  vm_scale(*vect, d, result);

  (*env)->ReleaseDoubleArrayElements(env, v, (jdouble *)vect, 0);
  (*env)->ReleaseDoubleArrayElements(env, res, (jdouble *)result, 0);

}

jdouble Java_net_matvec_Vector_vm_1magnitude(JNIEnv *env,
          jobject obj, jdoubleArray v){

  vm_vector *vect = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v, NULL);
  
  double mag = vm_magnitude(*vect);
  
  (*env)->ReleaseDoubleArrayElements(env, v, (jdouble *) vect, 0);

  return mag;

}

void Java_net_matvec_Vector_vm_1norm(JNIEnv *env, 
          jobject obj, jdoubleArray v, jdoubleArray res){

  vm_vector *vect = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v, NULL);
  vm_vector *result = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, res, NULL);

  vm_norm(*vect, result);

  (*env)->ReleaseDoubleArrayElements(env, v, (jdouble *)vect, 0);
  (*env)->ReleaseDoubleArrayElements(env, res, (jdouble *)result, 0);

}

void Java_net_matvec_Vector_vm_1cross(JNIEnv *env,
	  jobject obj, jdoubleArray v1, jdoubleArray v2, jdoubleArray res){

  vm_vector *vect1 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v1, NULL);
  vm_vector *vect2 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v2, NULL);
  vm_vector *result = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, res, NULL);

  vm_cross(*vect1, *vect2, result);

  (*env)->ReleaseDoubleArrayElements(env, v1, (jdouble *)vect1, 0);
  (*env)->ReleaseDoubleArrayElements(env, v2, (jdouble *)vect2, 0);
  (*env)->ReleaseDoubleArrayElements(env, res, (jdouble *)result, 0);

}

void Java_net_matvec_Vector_vm_1project(JNIEnv *env,
        jobject obj, jdoubleArray v1, jdoubleArray v2, jdoubleArray res){

  vm_vector *vect1 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v1, NULL);
  vm_vector *vect2 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v2, NULL);
  vm_vector *result = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, res, NULL);

  vm_project(*vect1, *vect2, result);

  (*env)->ReleaseDoubleArrayElements(env, v1, (jdouble *)vect1, 0);
  (*env)->ReleaseDoubleArrayElements(env, v2, (jdouble *)vect2, 0);
  (*env)->ReleaseDoubleArrayElements(env, res, (jdouble *)result, 0);

}

jdouble Java_net_matvec_Vector_vm_1dot(JNIEnv *env,
          jobject obj, jdoubleArray v1, jdoubleArray v2){

  vm_vector *vect1 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v1, NULL);
  vm_vector *vect2 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v2, NULL);
  
  double res;
  vm_dot(*vect1, *vect2, &res);

  (*env)->ReleaseDoubleArrayElements(env, v1, (jdouble *)vect1, 0);
  (*env)->ReleaseDoubleArrayElements(env, v2, (jdouble *)vect2, 0);

  return res;

}

jdouble Java_net_matvec_Vector_vm_1angle(JNIEnv * env,
          jobject obj, jdoubleArray v1, jdoubleArray v2){

  vm_vector *vect1 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v1, NULL);
  vm_vector *vect2 = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v2, NULL);
  
  double res = vm_angle(*vect1, *vect2);

  (*env)->ReleaseDoubleArrayElements(env, v1, (jdouble *)vect1, 0);
  (*env)->ReleaseDoubleArrayElements(env, v2, (jdouble *)vect2, 0);

  return res;

}

void Java_net_matvec_Vector_vm_1print(JNIEnv *env,
          jobject obj, jdoubleArray v){

  vm_vector *vect = (vm_vector *)
    (*env)->GetDoubleArrayElements(env, v, NULL);
  vm_print(*vect);
  (*env)->ReleaseDoubleArrayElements(env, v, (jdouble *)vect, 0);

}

void Java_net_matvec_Vector_vm_1println(JNIEnv *env, 
          jobject obj, jdoubleArray v){

  vm_vector *vect = (vm_vector *)(*env)->GetDoubleArrayElements(env, v, NULL);
  vm_println(*vect);
  (*env)->ReleaseDoubleArrayElements(env, v, (jdouble *)vect, 0);

}
